<?php
require_once("clases_gtk/zen_fabrica_gtk.php");
class zen_menu_gtk extends GtkMenuBar {
	/**
	* Objeto que se puede consturir a partir de una Cadena XML que lee el objeto DOMDocument o bien
	* desde una ruta de un fichero. Funciones para ello: $this->crear_desde_cadena($cadena_xml) o 
	* $this->crear_desde_xml($fichero)
	* @var DOMDocument
	*/
	var $xml;
	/**
	* Conjunto de widgets que componen el menú de la aplicación
	* @var array
	*/
	var $widgets = array();
	/**
	* Bandera para añadir un menú GTK para desprender los menús de su posición original y colocarlos
	* donde quiera el usario
	* @var bool
	*/
	var $anadirEnganches = true;
  /**
  * Constructor de menús
  * @return zen_menu_gtk
  */
	function __construct() {
		parent::__construct();
		$this->fabrica = zen_fabrica_gtk::obtenerFabrica();
	}
  /**
  * Llama a loadXML de DOMDocument con la $cadena XML
  * e intenta construir el menú de la aplicación que se define en dicha cadena
  * @param str $cadena
  */
	function crear_desde_cadena($cadena) {
		$this->xml = DOMDocument::loadXML($cadena);
		$this->inicio_construir();
	}
  /**
  * Llama a load de DOMDocument con el $fichero XML
  * e intenta construir el menú de la aplicación que se define en dicho fichero
  * @param str $fichero
  */
	function crear_desde_xml($fichero) {
		$this->xml = DOMDocument::load($fichero);
		$this->inicio_construir();
	}
	/**
	* Valida la cadena pasada o leida de un fichero y almacenada en el objeto $this->xml y
	* construye los menús a partir de los nodos que se definen en la estructura XML
	*/
	function inicio_construir() {
		if ($this->xml->validate()) {
		 $nodos = $this->xml->documentElement->childNodes;
		 $this->construir($this, $nodos);
		} else {
		 throw new Exception("Formato del XML incorrecto.");
		//trigger_error("Formato del XML incorrecto.");
		}
	}
  /**
  * Recorre los $nodos y con el objeto $obj va construyendo cada uno de sus items dentro del contenedor menú
  * @param zen_menu_gtk $obj
  * @param object $nodos
  */
	function construir($obj, $nodos) {
		foreach ($nodos as $nodo) {
			if ($nodo->nodeType != 1)
			 continue;
			$ret = $this->construirItems($nodo);
			$obj->append($ret);
		}
	}
  /**
  * Construye los items de un menú mediante la clase zen_fabrica_gtk
  * @param object $nodo
  * @param str $tipo
  * @return GtkImageMenuItem
  */
	function construirItems($nodo, $tipo = null) {
		$fabrica =& $this->fabrica;

		if (!$tipo)
		 $tipo = $nodo->nodeName;
		$id = $nodo->getAttribute("id");

		if ($tipo != "separador" && is_null($id)) {
		 throw new Exception("Item sin id");
		 //trigger_error("Item sin id");
		}

		$mostrar = $nodo->getAttribute("mostrar");
		$icono = $nodo->getAttribute("icono");
		$enganche = $nodo->getAttribute("arrancable") == "true";

		switch ($tipo) {
			case "item":
				if (!is_null($mostrar)) {
					if (!is_null($icono)) {
						$item = $fabrica->imagen_menuItem($mostrar);
						$imagen = $fabrica->icono($icono);
						$item->set_image($imagen);
					} else {
						$item = $fabrica->menuItem($mostrar);
					}
				} else if (!is_null($icono)) {
					$item = $fabrica->imagen_menuItem($icono);
				} else {
				 //trigger_error("Cada item debe tener al menos un icono o un texto para mostrar");
					throw new Exception("Cada item debe tener al menos un icono o un texto para mostrar");
				}
				$this->registrar($id, $item);
				return $item;

			case "separador":
				return $fabrica->separadorItem();

			default:
				$menu = $fabrica->menu();
				if ($enganche && $this->anadirEnganches)
					$menu->append($fabrica->enganche());
				$this->construir($menu, $nodo->childNodes);

				$item = $this->construirItems($nodo, "item");
				$item->set_submenu($menu);

				return $item;
		}
	}
  /**
  * Registra un widget, un objeto $obj con su $id, lo almacena en el array local $this->widgets
  * @param str $id
  * @param Object $obj
  */
	function registrar($id, $obj) {
		if (!array_key_exists($id, $this->widgets))
		 $this->widgets[$id] = $obj;
		else
		 //trigger_error("Ya hay un widget con ese ID");
		 throw new Exception("Ya hay un widget con ese ID");
	}
  /**
  * Devuelve el Objeto con el $id especificado
  * @param str $id
  * @return Object
  */
	function obtenerWidget($id) {
		if (array_key_exists($id, $this->widgets))
		 return $this->widgets[$id];
		else return null;
	}
  /**
  * Establece la bandera de añadir los elementos de enganche de un menú GTK, para
  * poder separarlos de la ventana y mostrarlos en una ventana separada
  * @param bool $anadir
  */
	function anadirEnganches($anadir=true) {
		$this->anadirEnganches = $anadir;
	}
}
?>
